<?php

namespace App\Models;

use App\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;

class Order extends Model
{
    // 等待支付
    const SHIP_STATUS_AWAITING_PAYMENT = 'awaiting_payment';
    // 支付失败
    const SHIP_STATUS_PAID_FAIL = 'paid_fail';
    // 待发货
    const SHIP_STATUS_PENDING = 'pending';
    // 待收货
    const SHIP_STATUS_DELIVERED = 'delivered';
    // 已收回（订单完成）
    const SHIP_STATUS_RECEIVED = 'received';
    // 超时取消
    const SHIP_STATUS_TIME_OUT = 'time_out';
    // 用户取消
    const SHIP_STATUS_CANCEL = 'cancel';
    // 用户退款
    const SHIP_STATUS_REFUND = 'refund';

    public static $shipStatusMap = [
        self::SHIP_STATUS_AWAITING_PAYMENT   => '待支付',
        self::SHIP_STATUS_PENDING            => '待发货',
        self::SHIP_STATUS_DELIVERED          => '已发货',
        self::SHIP_STATUS_RECEIVED           => '已完成',
        self::SHIP_STATUS_PAID_FAIL          => '支付失败',
        self::SHIP_STATUS_TIME_OUT           => '超时取消',
        self::SHIP_STATUS_CANCEL             => '已取消',
        self::SHIP_STATUS_REFUND             => '已退款',
    ];

    const TYPE_SECKILL = 'seckill';

    protected $fillable = [
        'order_sn',
        'type',
        'address',
        'total_amount',
        'original_price',
        'remark',
        'paid_at',
        'payment_method',
        'payment_no',
        'closed',
        'reviewed',
        'ship_status',
        'confirmed_at',
        'reviewed_at',
        'extra',
        'freight_price',
        'coupon_id',
        'cancel_delete',
        'refund_extra',
        'province',
        'city',
        'area',
    ];

    protected $appends = [
        'coupon_price',
        'order_amount'
    ];

    protected static function boot()
    {
        parent::boot();
        // 监听模型创建事件，在写入数据库之前触发
        static::creating(function ($model) {
            // 如果模型的 no 字段为空
            if (!$model->order_sn) {
                // 调用 findAvailableNo 生成订单流水号
                $model->order_sn = static::findAvailableNo();
                // 如果生成失败，则终止创建订单
                if (!$model->order_sn) {
                    return false;
                }
            }
        });
    }

    public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function items()
    {
        return $this->hasMany(OrderItem::class);
    }

    public function product()
    {
        return $this->belongsToMany(Product::class,'order_items','order_id','product_id');
    }

    public function coupon()
    {
        return $this->belongsTo(Coupon::class);
    }

    public function adjustments()
    {
        return $this->hasMany(Adjustments::class,'order_id', 'id');
    }

    public function refund()
    {
        return $this->hasMany(OrderRefundDetail::class,'order_id', 'id');
    }

    public function afterSale()
    {
        return $this->hasMany(AfterSale::class,'order_id', 'id');
    }

    public function sharedOrder()
    {
        return $this->hasOne(ShareProduct::class, 'order_id', 'id')->where('status', 1);
    }

    public static function findAvailableNo()
    {
        // 订单流水号前缀
        $prefix = date('YmdHis');
        for ($i = 0; $i < 10; $i++) {
            // 随机生成 6 位的数字
            $no = $prefix.str_pad(random_int(0, 999999), 6, '0', STR_PAD_LEFT);
            // 判断是否已经存在
            if (!static::query()->where('order_sn', $no)->exists()) {
                return $no;
            }
        }
        \Log::warning('订单号创建失败');
        return false;
    }

    // 拼接商品名称
    public function getProductNameAttribute()
    {
        $items = $this->items()->with('product')->get()->pluck('product.title');

        return Str::limit($items->implode(','),150);
    }

    // 格式化扩展参数
    public function getExtraAttribute($value)
    {
        return $this->attributes['extra'] = json_decode($value, true);
    }

    // 格式化收货地址
    public function getAddressAttribute($value)
    {
        return $this->attributes['address'] = json_decode($value, true);
    }

    /**
     * 获取优惠券优惠
     * @return mixed
     */
    public function getCouponPriceAttribute() {

        return $this->adjustments()->where('type', 'discount')->sum('amount');
    }

    /**
     * 获取订单总数量
     * @return mixed
     */
    public function getOrderAmountAttribute() {

        return $this->attributes['order_amount'] = $this->items()->sum('amount');
    }

    // 获取超时时间
    public function getOutTimeAttribute()
    {
        if ($this->ship_status == Order::SHIP_STATUS_AWAITING_PAYMENT) {
            // 增加 倒计时
            return Carbon::parse($this->created_at)->addMinutes(config('app.order_ttl'))->timestamp;
        }
        return 0;
    }

    // 获取分销分享着id
    public function getSharedMemberIdAttribute()
    {
        $shared = $this->sharedOrder()->first();

        if ($shared) {
            return $shared->member_id;
        }

        return 0;
    }
}
